﻿using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using Model.Enum;
using Model;
using System.Windows.Forms;

namespace SerailDriver
{
    public class SerailDriverCla
    {
        SerialPort sp = new SerialPort();
        public List<byte> ReturmData = new List<byte>();//缓存
        public int channelIndex = -1;
        public bool isTesting = false;
        public string channelName = "未知";
        public string SerialPortErr = string.Empty;
        public byte[] JustSendedBuffer = null;//记录刚发出的一帧数据
        private object lockObj = new object();
        public string Com = "";     
        //声明委托
        public delegate void ComPage(string anme,LogEnum log);
        //声明事件
        public event ComPage page;

        //串口返回的数据
        public delegate void QueryData(string data);
        public event QueryData queryData;

        public SerailDriverCla serailDriver;
        private List<AutoMsgModel> model;



        public void Clear() {
            ReturmData.Clear();
        }
        public SerailDriverCla()
        {
            

        }
        public SerailDriverCla(List<AutoMsgModel> model,string PortName, int BaudRate, string channelName = "未知", int channelIndex = -1)
        {

            this.model = model;
            if (PortName.Equals(string.Empty))
            {
                PortName = "COM1000";
            }
            Com = PortName;
            sp.PortName = PortName;
            sp.ReadBufferSize = 1028 * 10;
            sp.BaudRate = BaudRate;
            sp.DataBits = 8;
            sp.ReceivedBytesThreshold = 1;
            this.channelName = channelName;
            this.channelIndex = channelIndex;
        }

        //是否打开
        public bool IsOpen()
        {
#if DEBUG
          //  return true;
#endif
            
            int times = 2;
         //   xxx:
            try
            {
              
                return sp.IsOpen;
            }
            catch (Exception ex)
            {
                
            }
            return false;
        }

        //打开串口
        public bool Open()
        {
#if DEBUG
     //return true;       
#endif
            int times = 2;
            xxx:
            try
            {
               
                if (!sp.IsOpen)
                {
                    sp.Open();
                    sp.DataReceived += sp_DataReceived;
                }

                if (!sp.IsOpen)
                {
                    times--;
                    goto xxx;
                }
                return sp.IsOpen;
            }
            catch (Exception ex)
            {
                times--;
                if (times > 0)
                {
                    SerialPortErr = ex.Message.Replace("\r\n", string.Empty);
                    return false;
                }
                else
                {
                    goto xxx;
                }
            }
        }

        //关闭串口
        public bool Close()
        {
            try
            {
                if (sp.IsOpen)
                {
                    sp.DiscardOutBuffer();
                    sp.Close();
                    sp.DataReceived -= sp_DataReceived;
                    sp.Dispose();
                    Clear();
                }
                return !sp.IsOpen;
            }
            catch
            {
                return false;
            }
        }

        //接收事件
        private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {

           
            if (sp.BytesToRead == 0) return;
            int size = sp.BytesToRead;
            byte[] ReceBuf = new byte[size];
            try
            {
                sp.ReadTimeout = 5000 + size;
                sp.Read(ReceBuf, 0, size);
                lock (lockObj)
                {
                    //ComPage comPage = new ComPage();
                    //调用事件

                    // AddLog("收到消息:" + BitConverter.ToString(serailDriver.ReturmData.ToArray(), 0, serailDriver.ReturmData.Count), LogEnum.ReceverLog);
                    ReturmData.AddRange(ReceBuf);
                    page?.Invoke("收到消息:" + Encoding.UTF8.GetString(ReceBuf), LogEnum.ReceverLog);
                    string rece = Encoding.UTF8.GetString(ReceBuf);


                    /*//将数据添返回去
                    string receData = Encoding.GetEncoding("GB2312").GetString(ReceBuf);
                    queryData?.Invoke(receData);*/

                    autoresponse(rece, this.model);
                    //  ReturmData.Clear();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
  


        //每次修改model后保存
        public void modelsa(List<AutoMsgModel> models)
        {
            this.model = models;
        }
        public void autoresponse(string richtext, List<AutoMsgModel> mode)
        {
           // AutoUtil
            //ComPage cap ;
            /*List<AutoMsgModel> modelDataList = mode;*/
            List<AutoMsgModel> modelDataList = mode;
                if (modelDataList != null)
                {
                    for (int i = 0; i < modelDataList.Count; i++)
                    {
                      
                        //获取存储数据收到的信息
                        //获取存储数据收到的信息

                        bool us = modelDataList[i].Using;
                        if (us == true)
                        {
                            //字节转字符串
                            List<byte> rece = modelDataList[i].ReceverMsg; //收到信息
                            byte[] sreceve = rece.ToArray();
                            List<byte> SendMsgByteList = modelDataList[i].SendMsg;//回复信息
                            byte[] SendMsgData = SendMsgByteList.ToArray();
                            string send = Encoding.UTF8.GetString(SendMsgData);//回复信息
                            string recever = Encoding.UTF8.GetString(sreceve);//收到信息
                        if (richtext != null)
                        {
                            if (richtext.Trim().Equals(recever))
                            {
                                page?.Invoke("自动回复消息:" + send, LogEnum.SendLog);

                            }
                        }
                        }
                    }
                }
            
        }

        public bool ReceBuffer_Remove(byte b)
        {
            lock (lockObj)
            {
                return ReturmData.Remove(b);
            }
        }

        public bool ReceBuffer_RemoveAt(int index)
        {
            try
            {
                lock (lockObj)
                {
                    ReturmData.RemoveAt(index);
                }
                return true;
            }
            catch
            {
                return false;
            }
        }
  
        public bool ReceBuffer_RemoveRange(int index, int count)
        {
            try
            {
                lock (lockObj)
                {
                    ReturmData.RemoveRange(index, count);
                }
                return true;
            }
            catch
            {
                return false;
            }
        }

        public bool ReceBuffer_Clear()
        {
            try
            {
                lock (lockObj)
                {
                    Clear();

                }
                return true;
            }
            catch
            {
                return false;
            }
        }

        //发送数据
        public bool SendData(byte[] data, bool isRecordBuffer)
        {
#if DEBUG
        //    return true;
           
#endif     
           try
                {

                    if (sp.PortName == "COM1000")
                    {
                        return false;
                    }
                    sp.WriteTimeout = 100 + data.Length;

                    //if()
                    //this.sp.DiscardInBuffer();
                    //this.sp.DiscardOutBuffer();
                    Clear();
                    if (isRecordBuffer)
                        JustSendedBuffer = data;
                    if (!sp.IsOpen)
                    {
                        sp.Open();
                        sp.DataReceived += sp_DataReceived;
                    }
                    if (sp.IsOpen)
                    {
                        sp.Write(data, 0, data.Length);
                        return true;
                    }
                    else
                    {
                        if (Open())
                        {
                            sp.Write(data, 0, data.Length);
                            return true;
                        }
                    }
                }
                catch
                {
                    Close();
                    if (Open())
                    {
                        try
                        {
                            sp.Write(data, 0, data.Length);
                            return true;
                        }
                        catch { }
                    }
                }

            //   System.Windows.Forms.MessageBox.Show("串口未打开" + sp.PortName);
            return false;
        }
        /// <summary>
        /// 发送并且卡住s毫秒等待回复
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public byte[] SendAndWait(string x,int s) 
        {
            return null;
        }
        /// <summary>
        /// 发送并且卡住s毫秒等待回复
        /// </summary>
        /// <param name="s"></param>
        /// <returns></returns>
        public byte[] SendAndWait(byte[] x, int s)
        {
            return null;
        }
        //发送数据
        public bool SendDataString0A(string data)
        {
           
                if (sp.PortName == "COM1000")
                {
                    return false;
               }
                List<byte> tempList = new List<byte>();
                tempList.AddRange(Encoding.Default.GetBytes(data));
                tempList.Add(0x0A);
                if (sp.PortName == "COM10")
                {
                    Console.WriteLine("");
                }
                try
                {
                    sp.WriteTimeout = 100 + data.Length;

                    Clear();
                    if (!sp.IsOpen)
                    {
                        sp.Open();
                        sp.DataReceived += sp_DataReceived;
                    }
                    if (sp.IsOpen)
                    {
                        sp.Write(tempList.ToArray(), 0, tempList.Count);
                        tempList.Clear();
                        return true;
                    }
                    else
                    {
                        if (Open())
                        {
                            sp.Write(tempList.ToArray(), 0, tempList.Count);
                            tempList.Clear();
                            return true;
                        }
                    }
                }
                catch
                {
                    Close();
                    if (Open())
                    {
                        try
                        {
                            sp.Write(tempList.ToArray(), 0, tempList.Count);
                            tempList.Clear();
                            return true;
                        }
                        catch { }
                    }
                }
                tempList.Clear();
            
            return false;
        }

        //发送数据
        public bool SendDataStringEnter(string data)
        {
           try
                {
                    if (sp.PortName == "COM1000")
                    {
                        return false;
                    }
                    sp.WriteTimeout = 100 + data.Length;

                    if (sp.PortName == "COM10")
                    {
                        Console.WriteLine("");
                    }
                    if (!sp.IsOpen)
                    {
                        sp.Open();
                        sp.DataReceived += sp_DataReceived;
                    }
                    if (sp.IsOpen)
                    {
                        sp.WriteLine(data);
                        return true;
                    }
                    else
                    {
                        if (Open())
                        {
                            sp.WriteLine(data);
                            return true;
                        }
                    }
                }
                catch
                {
                    Close();
                    if (Open())
                    {
                        try
                        {
                            sp.WriteLine(data);
                            return true;
                        }
                        catch { }
                    }
                }
            
            return false;
        }

    }

}
